﻿using FieldTools.Client.Command;
using FieldTools.Client.Model.Window;
using FieldTools.Util;
using FieldTools.Util.Helper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace FieldTools.Client.ViewModel.Window
{
    /// <summary>
    /// 身份证视图模型
    /// </summary>
    public class IdentityCardViewModel : NotificationObject, ISingletonDependency
    {
        /// <summary>
        /// 
        /// </summary>
        public IdentityCardViewModel()
        {
            Console.WriteLine("打开身份证工具");
            //省市县选择初始化
            InItAdministrativeArea();
            //性别初始化
            InitSex();
            //年月日初始化
            InitDate();
            //描述内容
            InitTitleContent();
            //代数
            InitGeneration();
        }
        #region 实体

        IdentityCardModel obj = new();

        /// <summary>
        /// 省份数据
        /// </summary>
        public List<CodeContent>? Provinces
        {
            get => obj.Provinces;
            set
            {
                obj.Provinces = value;
                this.RaisePropertyChanged(nameof(Provinces));
            }
        }
        /// <summary>
        /// 选择的省份
        /// </summary>
        public CodeContent? Province
        {
            get => obj.Province;
            set
            {
                obj.Province = value;
                this.RaisePropertyChanged(nameof(Province));
            }
        }

        /// <summary>
        /// 选择的市
        /// </summary>
        public CodeContent? City
        {
            get => obj.City;
            set
            {
                obj.City = value;
                this.RaisePropertyChanged(nameof(City));
            }
        }

        /// <summary>
        /// 选择的县
        /// </summary>
        public CodeContent? County
        {
            get => obj.County;
            set
            {
                obj.County = value;
                this.RaisePropertyChanged(nameof(County));
            }
        }

        /// <summary>
        /// 年
        /// </summary>
        public List<CodeContent>? Years
        {
            get => obj.Years;
            set
            {
                obj.Years = value;
                this.RaisePropertyChanged(nameof(Years));
            }
        }
        /// <summary>
        /// 选择的年
        /// </summary>
        public CodeContent? Year
        {
            get => obj.Year;
            set
            {
                obj.Year = value;
                this.RaisePropertyChanged(nameof(Year));
            }
        }
        /// <summary>
        /// 月
        /// </summary>
        public List<CodeContent>? Months
        {
            get => obj.Months;
            set
            {
                obj.Months = value;
                this.RaisePropertyChanged(nameof(Months));
            }
        }
        /// <summary>
        /// 选择的月
        /// </summary>
        public CodeContent? Month
        {
            get => obj.Month;
            set
            {
                obj.Month = value;
                this.RaisePropertyChanged(nameof(Month));
            }
        }
        /// <summary>
        /// 日
        /// </summary>
        public List<CodeContent>? Days
        {
            get => obj.Days;
            set
            {
                obj.Days = value;
                this.RaisePropertyChanged(nameof(Days));
            }
        }
        /// <summary>
        /// 选择的日
        /// </summary>
        public CodeContent? Day
        {
            get => obj.Day;
            set
            {
                obj.Day = value;
                this.RaisePropertyChanged(nameof(Day));
            }
        }

        /// <summary>
        /// 性别
        /// </summary>
        public List<CodeContent>? Sexs
        {
            get => obj.Sexs;
            set
            {
                obj.Sexs = value;
                this.RaisePropertyChanged(nameof(Sexs));
            }
        }
        /// <summary>
        /// 选择的性别
        /// </summary>
        public CodeContent? Sex
        {
            get => obj.Sex;
            set
            {
                obj.Sex = value;
                this.RaisePropertyChanged(nameof(Sex));
            }
        }
        /// <summary>
        /// 身份证代数
        /// </summary>
        public List<CodeContent>? Generations
        {
            get => obj.Generations;
            set
            {
                obj.Generations = value;
                this.RaisePropertyChanged(nameof(Generations));
            }
        }
        /// <summary>
        /// 选择的身份证代数
        /// </summary>
        public CodeContent? Generation
        {
            get => obj.Generation;
            set
            {
                obj.Generation = value;
                this.RaisePropertyChanged(nameof(Generation));
            }
        }
        /// <summary>
        /// 输出身份证
        /// </summary>
        public string? IdentityCardText
        {
            get => obj.IdentityCardText;
            set
            {
                obj.IdentityCardText = value;
                this.RaisePropertyChanged(nameof(IdentityCardText));
            }
        }
        /// <summary>
        /// 输入身份证
        /// </summary>
        public string? IdentityCardInputText
        {
            get => obj.IdentityCardInputText;
            set
            {
                obj.IdentityCardInputText = value;
                this.RaisePropertyChanged(nameof(IdentityCardInputText));
            }
        }
        /// <summary>
        /// 描述内容
        /// </summary>
        public TitleContent? Content
        {
            get => obj.Content;
            set
            {
                obj.Content = value;
                this.RaisePropertyChanged(nameof(Content));
            }
        }
        /// <summary>
        /// 第二个描述内容
        /// </summary>
        public TitleContent? Content2
        {
            get => obj.Content2;
            set
            {
                obj.Content2 = value;
                this.RaisePropertyChanged(nameof(Content2));
            }
        }
        #endregion

        #region 事件

        private BaseCommand selectItemChangedCommand;
        /// <summary>
        /// 选择
        /// </summary>
        public BaseCommand SelectItemChangedCommand
        {
            get
            {
                if (selectItemChangedCommand == null)
                {
                    selectItemChangedCommand = new BaseCommand(new Action<object>(o =>
                    {
                        var con = o as ComboBox;
                        if (con != null)
                        {
                            CodeContent temp = con.SelectedItem.ToJson().ToObject<CodeContent>();
                            if (Year != null)
                            {
                                var year = Year.Code.TryToInt();
                                if (year!=null)
                                {
                                    if (Month != null)
                                    {
                                        var month = Month.Code.TryToInt();
                                        if (month != null)
                                        {
                                            Days = IsLeapYear(year.Value) && month.Value==2 ? MonthDays[12] : MonthDays[month.Value - 1];
                                        }
                                    }
                                    
                                }
                            }
                        }
                    }));
                }
                return selectItemChangedCommand;
            }
        }

        private BaseCommand createCommand;
        /// <summary>
        /// 生成
        /// </summary>
        public BaseCommand CreateCommand
        {
            get
            {
                if (createCommand == null)
                {
                    createCommand = new BaseCommand(new Action<object>(o =>
                    {
                        if(Year!=null && Month!=null && Day != null && County!=null && Sex!=null && Generation!=null)
                        {
                            string date = Year.Code + Month.Code + Day.Code;
                            var idNo = IdentityCardHelper.CreatIdentityCardNo(County.Code, date, Sex.Code.ToInt(),Generation.Code.ToInt());
                            IdentityCardText += idNo + "\r\n";
                        }
                        
                    }));
                }
                return createCommand;
            }
        }
        private BaseCommand checkCodeCommand;
        /// <summary>
        /// 校验
        /// </summary>
        public BaseCommand CheckCodeCommand
        {
            get
            {
                if (checkCodeCommand == null)
                {
                    checkCodeCommand = new BaseCommand(new Action<object>(o =>
                    {
                        if (IdentityCardInputText != null)
                        {
                            string[] idNos = IdentityCardInputText.Split("\r\n");
                            string msg = "校验结果：\r\n";
                            for(int i = 0; i < idNos.Length; i++)
                            {
                                if (IdentityCardHelper.CheckIdentityCardNo(idNos[i]))
                                {
                                    msg += idNos[i] + "通过\r\n";
                                }
                                else
                                {
                                    msg += idNos[i] + "不通过\r\n";
                                }
                            }
                            MessageBox.Show(msg);
                        }
                    }));
                }
                return checkCodeCommand;
            }
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// 每月天数集合，第13月表示润2月
        /// </summary>
        private List<List<CodeContent>> MonthDays { get; set; } = new();
        /// <summary>
        /// 初始化行政区，基础数据已在实体中初始化
        /// </summary>
        private void InItAdministrativeArea()
        {
            if (Provinces != null && Provinces.Any())
            {
                Province = Provinces.FirstOrDefault();
                if (Province != null && Province.Childs != null && Province.Childs.Any())
                {
                    City = Province.Childs.FirstOrDefault();
                    if (City != null && City.Childs != null && City.Childs.Any())
                    {
                        County = City.Childs.FirstOrDefault();
                    }
                }
            }
        }
        /// <summary>
        /// 初始化装载年月日
        /// </summary>
        private void InitDate()
        {
            //年
            Years = new List<CodeContent>();
            for (int i = 1900; i < 2100; i++)
            {
                string code = i.ToString();
                Years.Add(new()
                {
                    Code = code,
                    Name = code + "年",
                    Tag = 1
                });
            }
            Year = Years.FirstOrDefault();
            //月
            Months = new List<CodeContent>();
            for(int i = 0; i < 12; i++)
            {
                string code = i + 1 < 10 ? "0" + (i + 1).ToString() : (i + 1).ToString();
                Months.Add(new() {
                    Code = code,
                    Name = code+"月",
                    Tag = 2
                });
            }
            Month = Months.FirstOrDefault();
            //日，装载集合
            int[,] days2 = new int[13,31]
            {
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, 0, 0},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
                {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0},
            };
            
            for (int i = 0; i < 13; i++)
            {
                
                var days = new List<CodeContent>();
                for (int j = 0; j < 31; j++)
                {
                    if (days2[i, j] != 0)
                    {
                        string code = days2[i, j] < 10 ? "0" + days2[i, j].ToString() : days2[i, j].ToString();
                        days.Add(new()
                        {
                            Code = code,
                            Name = code + "日",
                            Tag = 3
                        });
                    }
                    
                }
                MonthDays.Add(days);
                if (i == 0)
                {
                    Days = days;
                    Day = Days.FirstOrDefault();
                }
            }

        }
        /// <summary>
        /// 初始化性别
        /// </summary>
        private void InitSex()
        {
            Sexs = new List<CodeContent>()
            {
                new(){Name="女",Code="0" },
                new(){Name="男",Code="1" },
            };
            Sex = Sexs.FirstOrDefault();
        }
        /// <summary>
        /// 初始化代数
        /// </summary>
        private void InitGeneration()
        {
            Generations = new List<CodeContent>()
            {
                new()
                {
                    Name = "1代",
                    Code = "01",
                    Tag = 4
                },
                new()
                {
                    Name = "2代",
                    Code = "02",
                    Tag = 4
                },
            };
            Generation = Generations[1];
        }
        private void InitTitleContent()
        {
            Content = new()
            {
                Title = "中国居民身份证号码编码规则",
                Content = @"第一、二位表示省（自治区、直辖市、特别行政区）。
第三、四位表示市（地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码）。其中，01-20，51-70表示省直辖市；21-50表示地区（自治州、盟）。
第五、六位表示县（市辖区、县级市、旗）。01-18表示市辖区或地区（自治州、盟）辖县级市；21-80表示县（旗）；81-99表示省直辖县级市。
第七、十四位表示出生年月日（单数字月日左侧用0补齐）。其中年份用四位数字表示，年、月、日之间不用分隔符。例如：1981年05月11日就用19810511表示。
第十五、十七位表示顺序码。对同地区、同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性，偶数分给女性。
第十八位表示校验码。作为尾号的校验码，是由号码编制单位按统一的公式计算出来的，校验码如果出现数字10，就用X来代替，详情参考下方计算方法。

其中第一代身份证号码为15位。年份两位数字表示，没有校验码。
前六位详情请参考省市县地区代码
X是罗马字符表示数字10，罗马字符（1-12）：Ⅰ、Ⅱ、Ⅲ、Ⅳ、Ⅴ、Ⅵ、Ⅶ、Ⅷ、Ⅸ、Ⅹ、Ⅺ、Ⅻ……，详情请参考罗马字符"
            };
            Content2 = new()
            {
                Title = "中国居民身份证校验码算法",
                Content = @"步骤如下：

将身份证号码前面的17位数分别乘以不同的系数。从第一位到第十七位的系数分别为：7－9－10－5－8－4－2－1－6－3－7－9－10－5－8－4－2。
将这17位数字和系数相乘的结果相加。
用加出来和除以11，取余数。
余数只可能有0－1－2－3－4－5－6－7－8－9－10这11个数字。其分别对应的最后一位身份证的号码为1－0－X－9－8－7－6－5－4－3－2。
通过上面计算得知如果余数是3，第18位的校验码就是9。如果余数是2那么对应的校验码就是X，X实际是罗马数字10。
例如：某男性的身份证号码为【53010219200508011x】， 我们看看这个身份证是不是合法的身份证。首先我们得出前17位的乘积和【(5*7)+(3*9)+(0*10)+(1*5)+(0*8)+(2*4)+(1*2)+(9*1)+(2*6)+(0*3)+(0*7)+(5*9)+(0*10)+(8*5)+(0*8)+(1*4)+(1*2)】是189，然后用189除以11得出的结果是189/11=17----2，也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以，可以判定这是一个正确的身份证号码。"

            };
        }
        /// <summary>
        /// 是否是闰年
        /// </summary>
        /// <param name="year"></param>
        /// <returns></returns>
        private static bool IsLeapYear(int year)
        {
            //4的倍数，不是100的倍数，是400的倍数)
            if((year%4==0 && year%100!=0) || year % 400 == 0)
            {
                return true;
            }
            return false;
        }
        #endregion
    }
}
